/**
 * 
 */
package kevin.study.zephyr.domain.model;

import java.util.Collection;
import java.util.Map;

import kevin.study.zephyr.domain.model.base.Base;
import kevin.study.zephyr.platform.Platform;


/**
 * 文档,存储所有信息的实例
 * 
 * @author Kevin.Huang
 * @date 2007-9-20
 */
public class Document extends Base {

	/**
	 * form对应的字段名
	 */
	public static final String FILTER_FORM = "form";

	/**
	 * items对应的字段名
	 */
	public static final String FILTER_ITEMS = "items";

	/**
	 * 
	 */
	private static final long serialVersionUID = 4516095025641240939L;

	private Document parentDocument;

	/**
	 * Docmument所依赖的模板
	 */
	private Form form;

	/**
	 * Document所包含的字段
	 */
	private Collection< Item > items;

	/**
	 * 对Item建的索引
	 */
	private Map< String, Collection< Item >> indexItems;

	@Override
	public void init() {
		super.init();
		if (items != null) {
			for (Item i : items) {
				i.init();
			}
		}
	}

	/**
	 * 根据域名取得item
	 * 
	 * @param name
	 * @return
	 */
	public Collection< Item > getItemsByName(String name) {
		if (indexItems == null) {
			Platform.getDocumentManager().getDocumentFactory().indexItem(this);
		}
		return indexItems.get(name);
	}

	@SuppressWarnings("unchecked")
	private Entity getFirstEntityByName(String name) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			Item i = is.iterator().next();
			if (i.getEntity() != null && !i.getEntity().isEmpty()) {
				return i.getEntity().iterator().next();
			} else {
				return null;
			}
		} else {
			return null;
		}
	}

	/**
	 * 在此document临时添加一个Item(不被持久化)
	 * 
	 * @param name
	 *            item名
	 * @param type
	 *            item的类型
	 * @param value
	 *            item的值
	 * @return 创建的item
	 */
	public Item appendItemValue(String name, String type, Object value) {
		Field field = new Field();
		field.setType(type);
		Item item = new Item();
		item.setField(field);
		item.setValue(value);
		return item;
	}

	/**
	 * 给第一个取到的Item输入值
	 * 
	 * @param name
	 * @param value
	 */
	public void setFirstItem(String name, Object value) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			is.iterator().next().setValue(value);
		}
	}

	/**
	 * 给第一个取到的Item输入值
	 * 
	 * @param name
	 * @param value
	 */
	public void setFirstItem(String name, Collection< Object > value) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			is.iterator().next().setValues(value);
		}
	}

	/**
	 * 给第一个取到的Item添加一个值
	 * 
	 * @param name
	 * @param value
	 */
	public void appendValueToFirstItem(String name, Object value) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			is.iterator().next().appendToList(value);
		}
	}

	/**
	 * 给第一个取到的Item输入String值
	 * 
	 * @param name
	 * @param value
	 */
	public void setStringValuesToFirstItem(String name, String value) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			is.iterator().next().setStringValue(value);
		}
	}

	/**
	 * 给第一个取到的Item输入String值
	 * 
	 * @param name
	 * @param value
	 */
	public void setStringValuesToFirstItem(String name, Collection< String > value) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			is.iterator().next().setStringValues(value);
		}
	}

	/**
	 * 从第一个Item中取第一个值
	 * 
	 * @param <A>
	 * @param name
	 * @return
	 */
	public < A > A getFirstItem(String name) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			return is.iterator().next().getValue();
		} else {
			return null;
		}
	}

	/**
	 * 从第一个Item中取所有值
	 * 
	 * @param <A>
	 * @param name
	 * @return
	 */
	public < A > Collection< A > getFirstItems(String name) {
		Collection< Item > is = getItemsByName(name);
		if (is != null && !is.isEmpty()) {
			return is.iterator().next().getValues();
		} else {
			return null;
		}
	}

	/**
	 * 保存文档,若无对应Form,则不保存
	 */
	public Document save() {
		this.init();
		if (this.form != null) {
			Platform.getDocumentManager().getDocumentFactory().formatDocumentByForm(this);
			return Platform.getDocumentManager().getDocumentDAO().saveAndUpdate(this);
		} else {
			throw new RuntimeException("Form is not Exist!Can't save this Document!");
		}
	}

	/**
	 * 删除此文档
	 */
	public void delete() {
		Platform.getDocumentManager().getDocumentDAO().delete(this);
	}

	/**
	 * @return the form
	 */
	public Form getForm() {
		return form;
	}

	/**
	 * @param form
	 *            the form to set
	 */
	public void setForm(Form form) {
		this.form = form;
	}

	/**
	 * @return the items
	 */
	public Collection< Item > getItems() {
		return items;
	}

	/**
	 * @param items
	 *            the items to set
	 */
	public void setItems(Collection< Item > items) {
		this.items = items;
	}

	/**
	 * @return the indexItems
	 */
	public Map< String, Collection< Item >> getIndexItems() {
		return indexItems;
	}

	/**
	 * @param indexItems
	 *            the indexItems to set
	 */
	public void setIndexItems(Map< String, Collection< Item >> indexItems) {
		this.indexItems = indexItems;
	}

	/**
	 * @return the parentDocument
	 */
	public Document getParentDocument() {
		return parentDocument;
	}

	/**
	 * @param parentDocument
	 *            the parentDocument to set
	 */
	public void setParentDocument(Document parentDocument) {
		this.parentDocument = parentDocument;
	}

	/**
	 * 比较
	 * 
	 * @param o
	 * @param fieldName
	 *            对相应的域进行比较
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public int compareTo(Document o, String fieldName) {
		Entity thisEntity = this.getFirstEntityByName(fieldName);
		Entity anotherEntity = o.getFirstEntityByName(fieldName);
		if (thisEntity == null) {
			if (anotherEntity == null) {
				return 0;
			} else {
				return -1;
			}
		} else {
			if (anotherEntity == null) {
				return 1;
			} else {
				return thisEntity.compareTo(anotherEntity);
			}
		}
	}

}
